#ifndef __LINUX_FDTABLE_H
#define __LINUX_FDTABLE_H

#include <linux/fs2.h>
#include <linux/rcupdate.h>

#define NR_OPEN_DEFAULT BITS_PER_LONG

struct fdtable {
	unsigned int max_fds;
	struct file ** fd;      /* current fd array */
	// fd_set *close_on_exec;
	// fd_set *open_fds;
	// struct rcu_head rcu;
	struct fdtable *next;
};

struct files_struct {
  /*
   * read mostly part
   */
	atomic_t count;
	struct fdtable *fdt;
	struct fdtable fdtab;
  /*
   * written part on a separate cache line in SMP
   */
	// spinlock_t file_lock ____cacheline_aligned_in_smp;
	int next_fd;
	// struct embedded_fd_set close_on_exec_init;
	// struct embedded_fd_set open_fds_init;
	struct file * fd_array[NR_OPEN_DEFAULT];
};

#define files_fdtable(files) (rcu_dereference((files)->fdt))

static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
{
	struct file * file = NULL;
	struct fdtable *fdt = files_fdtable(files);

	// if (fd < fdt->max_fds)
		file = rcu_dereference(fdt->fd[fd]);
	return file;
}

#endif
